'use strict'; // 确保严格模式，修改冻结对象会抛出错误

/**
 * 创建一个被冻结的只读字典对象
 * 包含用户信息的数据集
 */
const createReadOnlyDict = (dictionary) => {
    // 深度冻结函数 - 递归冻结对象及其所有属性（包括嵌套数组）
    const deepFreeze = (obj) => {
        // 获取对象的所有属性名（包括不可枚举属性）
        const propNames = Object.getOwnPropertyNames(obj);

        // 冻结对象本身
        Object.freeze(obj);

        // 递归冻结所有属性
        for (const name of propNames) {
            const prop = obj[name];
            // 如果属性是对象或数组且未被冻结，则递归冻结
            if (typeof prop === 'object' && prop !== null && !Object.isFrozen(prop)) {
                deepFreeze(prop);
            }
        }

        return obj;
    };

    // 深度冻结数组中的每个元素（包括可能的嵌套数组）
    return deepFreeze(dictionary);
};

/**
 * 生成值到对象的映射
 * @param {Array} dictArray - 字典数组
 * @returns {Object} 以value为键的映射对象
 */
const getDictMap = (dictArray) => {
    const result = {}; // 先创建一个空对象
    for (const item of dictArray) { // 遍历数组
        result[item.value] = item; // 用 item.value 作为键，item 作为值
    }
    // 返回生成的对象
    return createReadOnlyDict(result);
};

/**
 * 为所有字典生成映射对象
 * @param {Object} dictObj - 包含多个字典的对象
 * @returns {Object} 包含所有字典映射的对象
 */
const getAllDictMap = (dictObj) => {
    // 获取对象的所有属性名（包括不可枚举属性）
    const propNames = Object.getOwnPropertyNames(dictObj);
    const result = {}; // 先创建一个空对象
    // 所有属性
    for (const name of propNames) {
        //获取数组
        const dictArray = dictObj[name];
        const dictMapName = `${name}_MAP`;//生成新的属性名
        //赋值
        result[dictMapName]=getDictMap(dictArray);
    }
    // 返回生成的对象
    return createReadOnlyDict(result);
};

// 2. 创建测试数据
// const fruits = [
//     { name: "Apple", value: "a" },
//     { name: "Banana", value: "b" }
// ];
//
// const colors = [
//     { name: "Red", value: 1 },
//     { name: "Blue", value: 2 }
// ];
//
// // 3. 简单测试演示
// console.log("----- 基础功能测试 -----");
//
// // 测试1：普通对象能否被冻结
// console.log("测试1: 冻结水果数组");
// const frozenFruits = createReadOnlyDict(fruits);
// try {
//     frozenFruits[0].name = "测试破坏";
//     console.log("❌ 测试失败：应该阻止修改");
// } catch {
//     console.log("✅ 测试通过：成功阻止修改");
// }
//
// // 测试2：生成颜色映射
// console.log("\n测试2: 生成颜色映射");
// const colorMap = getDictMap(colors);
// console.log("生成的映射:", colorMap);
// console.log("通过键访问颜色:", colorMap[1].name);  // 应该输出"Red"
//
// // 测试3：批量生成多个映射
// console.log("\n测试3: 批量生成字典映射");
// const allMaps = getAllDictMap({ fruits, colors });
// console.log("水果映射:", allMaps.fruits_MAP);
// console.log("颜色映射:", allMaps.colors_MAP);
// console.log("查找香蕉:", allMaps.fruits_MAP.b.name);  // 应该输出"Banana"
//
// // 4. 破坏性测试
// console.log("\n----- 防破坏测试 -----");
// try {
//     allMaps.colors_MAP[2] = "hacked";
//     console.log("❌ 测试失败：修改根映射未被阻止");
// } catch {
//     console.log("✅ 测试通过：阻止了根映射修改");
// }
//
// try {
//     allMaps.fruits_MAP.a.name = "Hacked Apple";
//     console.log("❌ 测试失败：修改嵌套属性未被阻止");
// } catch {
//     console.log("✅ 测试通过：阻止了嵌套属性修改");
// }

// 导出只读字典
export {
    createReadOnlyDict,
    getAllDictMap
};